package signGrammar.expressions.util;

import java.util.HashMap;
import java.util.Map;

import signGrammar.expressions.CBinaryExpression;
import signGrammar.expressions.CUnaryExpression;
import signGrammar.expressions.CVariable;
import signGrammar.expressions.IGrammarExpression;


public class UExpression {
	private UExpression() {}
	
	
	public static Map<String, IBinaryExpression> getBinaryExpressions(){
		return binaryExpressionsMap;
	}
	
	static Map<String, IBinaryExpression> binaryExpressionsMap;
	static {
		binaryExpressionsMap = new HashMap<String, IBinaryExpression>();
		binaryExpressionsMap.put("+", new IBinaryExpression(){
			@Override
			public IGrammarExpression eval(IGrammarExpression left, IGrammarExpression right) {
				return new CBinaryExpression(left,"+",right);
			}});
		binaryExpressionsMap.put("-", new IBinaryExpression(){
			@Override
			public IGrammarExpression eval(IGrammarExpression left, IGrammarExpression right) {
				return new CBinaryExpression(left,"-",right);
			}});
		binaryExpressionsMap.put("x", new IBinaryExpression(){
			@Override
			public IGrammarExpression eval(IGrammarExpression left, IGrammarExpression right) {
				return new CBinaryExpression(left,"x",right);
			}});
	}
	public static IGrammarExpression eval(IGrammarExpression left, String binaryExpressionSign, IGrammarExpression right){
		return binaryExpressionsMap.get(binaryExpressionSign).eval(left, right);
	}
	
	public static Map<String, IUnaryExpression> getUnaryExpressions(){
		return unaryExpressionEvaluators;
	}
		
	static Map<String, IUnaryExpression> unaryExpressionEvaluators;
	static{
		unaryExpressionEvaluators = new HashMap<String, IUnaryExpression>();
		unaryExpressionEvaluators.put("~", new IUnaryExpression(){
			@Override public IGrammarExpression eval(IGrammarExpression expression) {
				return new CUnaryExpression("~", expression);
			}});
	}
	public static IGrammarExpression eval(String unaryExpressionSign, IGrammarExpression expression){
		return unaryExpressionEvaluators.get(unaryExpressionSign)
			.eval(expression);
	}
	
	public static class CVariableMapBuilder {
		protected static Map<String, CVariable> createMap() {
			return new HashMap<String, CVariable>();
		}
		private Map<String, CVariable> variables = createMap();
		public CVariableMapBuilder add(String[] names){
			for(String name : names)
				variables.put(name, CVariable.create(name));
			return this;
		}
		public CVariableMapBuilder add(String name){
			variables.put(name, CVariable.create(name));
			return this;
		}
		public Map<String, CVariable> get(){
			Map<String, CVariable> toReturn = variables;
			variables = createMap();
			return toReturn;
		}
	}
	
	
	public static CVariableMapBuilder createVariableMapBuilder(){
		return new CVariableMapBuilder();
	}
}
